﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using SpeedikonCom;
using System.Xml.Serialization;

namespace SOM.Objects
{
  [Serializable()]
  [ComDefaultInterface(typeof(SOM.Interfaces.Objects.IRoom)), ClassInterface(ClassInterfaceType.None)]
  [ComSourceInterfaces(typeof(SOM.Interfaces.Objects.IRoom))]
  public partial class Room : SOM.Interfaces.Objects.IRoom
  {
    bool _readOnly = false;
    internal void SetPropertiesReadOnly(bool ReadOnly)
    {
      _readOnly = ReadOnly;
    }

    public Room()
    {
      _props = this.GetType().GetProperties();
      //initRaum();
    }
    private System.Reflection.PropertyInfo[] _props;

    public void SendToDatabase(string server, string table, string SchemeFilePath = "")
    {
      SOM.Helper.Methods.SendToDatabase<SOM.Objects.Room>(this, server,table,SchemeFilePath);
    }
    public void GetFromDatabase(string server, int ID, string table, string SchemeFilePath = "")
    {
      var tmp = (SOM.Interfaces.Objects.IRoom)SOM.Helper.Methods.GetFromDatabase<SOM.Objects.Room>(server, ID,table,SchemeFilePath);
      foreach (System.Reflection.PropertyInfo p in this.GetType().GetProperties())
      {
        try { this.GetType().GetProperty(p.Name).SetValue(this, tmp.GetType().GetProperty(p.Name).GetValue(tmp, null), null); }
        catch { }
      }
    }

    #region globale Variablen
    [ComVisible(false)]
    Dictionary<string, int> ldObjektTyp = new Dictionary<string, int>();
    [ComVisible(false)]
    List<string> scObjektName = new List<string>();
    [ComVisible(false)]
    Dictionary<string, string> sdObjektZellName = new Dictionary<string, string>();
    [ComVisible(false)]
    Dictionary<string, Dictionary<string, string>> sddObjektAttribut = new Dictionary<string, Dictionary<string, string>>();
    #endregion

    #region Typen-Konstanten
    const string sRaumName = "Raum";
    [ComVisible(false)]
    const string sRaumZellName = "space_";
    #endregion


    private SOM.Interfaces.Lists.IWallList _Walls = new Lists.WallList();


    private SOM.Interfaces.Lists.IOpeningList _Openings = new Lists.OpeningList();

    [XmlIgnore]
    public SOM.Interfaces.Lists.IOpeningList Openings { get { return _Openings; } set { _Openings = value; } }

    [XmlIgnore]
    public SOM.Interfaces.Lists.IWallList Walls { get { return _Walls; } set { _Walls = value; } }


    private int[] _WallIds;
    private int[] _OpeningIds;

    public int[] WallIds { get { return _WallIds; } set { _WallIds = value; } }

    public int[] OpeningIds { get { return _OpeningIds; } set { _OpeningIds = value; } }


    public bool Delete()
    {
      IEZ_sp_Object o = new IEZ_sp_Object();
      int iRet;
      o.Delete((int)SOM.Helper.enums.ObjektTypen.Room, this.ID, out iRet);
      if (iRet != 0)
        return false;
      else
        return true;
    }

    public bool Place(ref SOM.Helper.Types.Point3d Origin)
    {
      throw new NotImplementedException("COM-Interface doesn't support placing Rooms!");
      
      //IEZ_sp_Space w = new IEZ_sp_Space();
      //int iRet;
      //w.InitPlace(200, this.A_PROTOTYPE, out iRet);
      //if (iRet != 0)
      //  return false;
      //else
      //{
      //  w.Place(this.StartPointAxis.X, this.StartPointAxis.Y, this.EndPointAxis.X, this.EndPointAxis.Y, out iRet);
      //  if (iRet != 0)
      //    return false;
      //  else
      //    return true;
      //}
    }

    public object GetCustomAttribute(string AttributeName, SOM.Helper.enums.ReturnType ReturnType, out int iRet)
    {
        int lStatus = 0;
        int Anz;
        double dVal = 0;
        double[] daVal = null;
        int lVal = 0;
        int[] laVal = null;
        string sVal = null;
        string[] saVal = null;
        object ret = null;

        int Typ = (int)SOM.Helper.enums.ObjektTypen.Room;
        IEZ_sp_Attribute cAttribut = new IEZ_sp_Attribute();
        switch (ReturnType)
        {
            case SOM.Helper.enums.ReturnType.Double:
                dVal = 0;
                cAttribut.GetDouble((int)Typ, ID, AttributeName, out dVal, out lStatus);
                if (lStatus == 0)
                {
                    ret = dVal;
                }

                break;
            case SOM.Helper.enums.ReturnType.DoubleArray:
                daVal = null;
                Anz = 0;
                cAttribut.GetArraySize(Typ, ID, AttributeName, out Anz, out lStatus);
                cAttribut.GetDoubleArray(Typ, ID, AttributeName, 0, Anz, out daVal, out lStatus);
                if (lStatus == 0)
                {
                    ret = daVal;
                }
                break;
            case SOM.Helper.enums.ReturnType.Integer:
                lVal = 0;
                cAttribut.GetInt(Typ, ID, AttributeName, out lVal, out lStatus);
                if (lStatus == 0)
                {
                    ret = lVal;
                }
                break;
            case SOM.Helper.enums.ReturnType.IntegerArray:
                laVal = null;
                Anz = 0;
                cAttribut.GetArraySize(Typ, ID, AttributeName, out Anz, out lStatus);
                cAttribut.GetIntArray(Typ, ID, AttributeName, 0, Anz, out laVal, out lStatus);
                if (lStatus == 0)
                {
                    ret = laVal;
                }
                break;
            case SOM.Helper.enums.ReturnType.String:
                sVal = null;
                cAttribut.GetChar(Typ, ID, AttributeName, out sVal, out lStatus);
                if (lStatus == 0)
                {
                    ret = sVal;
                }
                break;
            case SOM.Helper.enums.ReturnType.StringArray:
                saVal = null;
                Anz = 0;
                cAttribut.GetArraySize(Typ, ID, AttributeName, out Anz, out lStatus);
                cAttribut.GetCharArray(Typ, ID, AttributeName, 0, Anz, out saVal, out lStatus);
                if (lStatus == 0)
                {
                    ret = saVal;
                }
                break;
            default:
                lStatus = -9999;
                break;
        }
        iRet = lStatus;
        return ret;
    }

  
    public void LoadRoom(int RoomID)
    {
      
      List<string> sdObjektName = new List<string>();
      Dictionary<string, string> sddOjektAttribut = new Dictionary<string, string>();

      Dictionary<string, string> sdAttribute = new Dictionary<string, string>();
      //  IEZ_sp_Attribute cAttribut = new IEZ_sp_Attribute();
      IEZ_sp_Space clRoom = new IEZ_sp_Space();
      IEZ_sp_Object clObject = new IEZ_sp_Object();
      //int lStatus;


      this.ID = RoomID;

      #region "Generic Property Setter"
      int lStatus;

      int Anz = 0;

      double dVal = 0;
      double[] daVal = null;
      int lVal = 0;
      int[] laVal = null;
      string sVal = null;
      string[] saVal = null;

      int Typ = (int)SOM.Helper.enums.ObjektTypen.Room;
      IEZ_sp_Attribute cAttribut = new IEZ_sp_Attribute();



      foreach (System.Reflection.PropertyInfo p in _props)
      {
        if (p.PropertyType == typeof(double))
        {
          dVal = 0;
          cAttribut.GetDouble((int)Typ, ID, p.Name, out dVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, dVal, null);
          }
        }
        else if (p.PropertyType == typeof(double[]))
        {
          daVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, p.Name, out Anz, out lStatus);
          cAttribut.GetDoubleArray(Typ, ID, p.Name, 0, Anz, out daVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, daVal, null);
          }
        }
        else if (p.PropertyType == typeof(int))
        {
          lVal = 0;
          cAttribut.GetInt(Typ, ID, p.Name, out lVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, lVal, null);
          }
        }
        else if (p.PropertyType == typeof(int[]))
        {
          laVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, p.Name, out Anz, out lStatus);
          cAttribut.GetIntArray(Typ, ID, p.Name, 0, Anz, out laVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, laVal, null);
          }
        }
        else if (p.PropertyType == typeof(string))
        {
          sVal = null;
          cAttribut.GetChar(Typ, ID, p.Name, out sVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, sVal, null);
          }
        }
        else if (p.PropertyType == typeof(string[]))
        {
          saVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, p.Name, out Anz, out lStatus);
          cAttribut.GetCharArray(Typ, ID, p.Name, 0, Anz, out saVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, saVal, null);
          }
        }
      }
      #endregion


      ReloadSubObjects();

      this.SetPropertiesReadOnly(true);
    }

    public void ReloadSubObjects()
    {
      int lStatus;
      int iCount;
      int[] iIDs;
      SpeedikonCom.IEZ_sp_Space clRoom = new IEZ_sp_Space();
      clRoom.GetList(this.ID, (int)SOM.Helper.enums.ObjektTypen.Wall, out iCount, out iIDs, out lStatus);
      this._WallIds = iIDs;
      ((SOM.Lists.WallList)Walls).Clear();
      for (int i = 0; i < iCount; i++)
      {
        SOM.Objects.Wall w = new Wall();
        w.LoadWall(iIDs[i]);
        ((SOM.Lists.WallList)Walls).Add(w);
      }

      iCount = 0;
      iIDs = null;

      clRoom.GetList(this.ID, (int)SOM.Helper.enums.ObjektTypen.Opening, out iCount, out iIDs, out lStatus);
      this._OpeningIds = iIDs;
      ((SOM.Lists.OpeningList)Openings).Clear();
      for (int i = 0; i < iCount; i++)
      {
        SOM.Objects.Opening w = new Opening();
        w.LoadOpening(iIDs[i]);
        ((SOM.Lists.OpeningList)Openings).Add(w);
      }
    }

   
  }
}
